home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / jpsrc2.zip / JDMAIN.C < prev    next >
C/C++ Source or Header  |  1991-12-13  |  9KB  |  342 lines

  1. /*
  2.  * jdmain.c
  3.  *
  4.  * Copyright (C) 1991, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains a trivial test user interface for the JPEG decompressor.
  9.  * It should work on any system with Unix- or MS-DOS-style command lines.
  10.  *
  11.  * Two different command line styles are permitted, depending on the
  12.  * compile-time switch TWO_FILE_COMMANDLINE:
  13.  *    djpeg [options]  inputfile outputfile
  14.  *    djpeg [options]  [inputfile]
  15.  * In the second style, output is always to standard output, which you'd
  16.  * normally redirect to a file or pipe to some other program.  Input is
  17.  * either from a named file or from standard input (typically redirected).
  18.  * The second style is convenient on Unix but is unhelpful on systems that
  19.  * don't support pipes.  Also, you MUST use the first style if your system
  20.  * doesn't do binary I/O to stdin/stdout.
  21.  */
  22.  
  23. #include "jinclude.h"
  24. #ifdef INCLUDES_ARE_ANSI
  25. #include <stdlib.h>        /* to declare exit() */
  26. #endif
  27.  
  28. #ifdef THINK_C
  29. #include <console.h>        /* command-line reader for Macintosh */
  30. #endif
  31.  
  32. #ifdef DONT_USE_B_MODE        /* define mode parameters for fopen() */
  33. #define READ_BINARY    "r"
  34. #define WRITE_BINARY    "w"
  35. #else
  36. #define READ_BINARY    "rb"
  37. #define WRITE_BINARY    "wb"
  38. #endif
  39.  
  40. #include "jversion.h"        /* for version message */
  41.  
  42.  
  43. /*
  44.  * PD version of getopt(3).
  45.  */
  46.  
  47. #include "egetopt.c"
  48.  
  49.  
  50. /*
  51.  * This list defines the known output image formats
  52.  * (not all of which need be supported by a given version).
  53.  * You can change the default output format by defining DEFAULT_FMT;
  54.  * indeed, you had better do so if you undefine PPM_SUPPORTED.
  55.  */
  56.  
  57. typedef enum {
  58.     FMT_GIF,        /* GIF format */
  59.     FMT_PPM,        /* PPM/PGM (PBMPLUS formats) */
  60.     FMT_RLE,        /* RLE format */
  61.     FMT_TARGA,        /* Targa format */
  62.     FMT_TIFF        /* TIFF format */
  63. } IMAGE_FORMATS;
  64.  
  65. #ifndef DEFAULT_FMT        /* so can override from CFLAGS in Makefile */
  66. #define DEFAULT_FMT    FMT_PPM
  67. #endif
  68.  
  69. #ifdef MSDOS
  70. #define DEFAULT_FMT_EXT "tga"
  71. #define JPEG_EXT        "jpg"
  72. #endif
  73.  
  74. static IMAGE_FORMATS requested_fmt;
  75.  
  76.  
  77. /*
  78.  * This routine gets control after the input file header has been read.
  79.  * It must determine what output file format is to be written,
  80.  * and make any other decompression parameter changes that are desirable.
  81.  */
  82.  
  83. METHODDEF void
  84. d_ui_method_selection (decompress_info_ptr cinfo)
  85. {
  86.   /* if grayscale or CMYK input, force similar output; */
  87.   /* else leave the output colorspace as set by options. */
  88.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  89.     cinfo->out_color_space = CS_GRAYSCALE;
  90.   else if (cinfo->jpeg_color_space == CS_CMYK)
  91.     cinfo->out_color_space = CS_CMYK;
  92.  
  93.   /* select output file format */
  94.   /* Note: jselwxxx routine may make additional parameter changes,
  95.    * such as forcing color quantization if it's a colormapped format.
  96.    */
  97.   switch (requested_fmt) {
  98. #ifdef GIF_SUPPORTED
  99.   case FMT_GIF:
  100.     jselwgif(cinfo);
  101.     break;
  102. #endif
  103. #ifdef PPM_SUPPORTED
  104.   case FMT_PPM:
  105.     jselwppm(cinfo);
  106.     break;
  107. #endif
  108. #ifdef RLE_SUPPORTED
  109.   case FMT_RLE:
  110.     jselwrle(cinfo);
  111.     break;
  112. #endif
  113. #ifdef TARGA_SUPPORTED
  114.   case FMT_TARGA:
  115.     jselwtarga(cinfo);
  116.     break;
  117. #endif
  118.   default:
  119.     ERREXIT(cinfo->emethods, "Unsupported output file format");
  120.     break;
  121.   }
  122. }
  123.  
  124.  
  125. LOCAL void
  126. usage (char * progname)
  127. /* complain about bad command line */
  128. {
  129.   fprintf(stderr, "usage: %s ", progname);
  130.   fprintf(stderr, "[-G] [-P] [-R] [-T] [-b] [-g] [-q colors] [-2] [-D] [-d]");
  131. #ifdef TWO_FILE_COMMANDLINE
  132. #    ifdef MSDOS
  133.   fprintf(stderr, " inputfile [outputfile]\n");
  134. #    else
  135.   fprintf(stderr, " inputfile outputfile\n");
  136. #    endif
  137. #else
  138.   fprintf(stderr, " [inputfile]\n");
  139. #endif
  140.   exit(2);
  141. }
  142.  
  143. #ifdef MSDOS
  144.  
  145. /*
  146.  * Compose a filename given a base name and extension.  If file had
  147.  * and extension, throw it away.  We must scan the filename from the
  148.  * right looking for a '.', but stopping if we encounter a path
  149.  * separator character (just in case we are handled a long pathname
  150.  * in which one of the directories has a '.', but the file doesn't).
  151.  */
  152.  
  153. LOCAL void
  154. fix_msdos_filename (char *dest, char *src, char *ext)
  155. {
  156.   int i, l;
  157.   char *dotp;
  158.  
  159.   strcpy(dest, src);
  160.   l = strlen(dest);
  161.   dotp = dest + l; /* Assume there is no extension */
  162.  
  163.   for (i = --l; i >= 0; --i) {
  164.     if (dest[i] == '.') {
  165.       dotp = dest + i;
  166.       break;
  167.     } else if ( dest[i] == '/' || dest[i] == '\\' ||
  168.                 dest[i] == ':') {
  169.       break;
  170.     }
  171.   }
  172.   *dotp++ = '.';
  173.   strcpy(dotp, ext);
  174. }
  175.  
  176. #endif /* MSDOS */
  177.  
  178. /*
  179.  * The main program.
  180.  */
  181.  
  182. GLOBAL void
  183. main (int argc, char **argv)
  184. {
  185. #ifdef MSDOS
  186.   char infname[FILENAME_MAX], outfname[FILENAME_MAX];
  187. #endif
  188.   struct decompress_info_struct cinfo;
  189.   struct decompress_methods_struct dc_methods;
  190.   struct external_methods_struct e_methods;
  191.   int c;
  192.  
  193.   /* On Mac, fetch a command line. */
  194. #ifdef THINK_C
  195.   argc = ccommand(&argv);
  196. #endif
  197.  
  198.   /* Initialize the system-dependent method pointers. */
  199.   cinfo.methods = &dc_methods;
  200.   cinfo.emethods = &e_methods;
  201.   jselerror(&e_methods);    /* error/trace message routines */
  202.   jselvirtmem(&e_methods);    /* memory allocation routines */
  203.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  204.  
  205.   /* Set up default JPEG parameters. */
  206.   j_d_defaults(&cinfo, TRUE);
  207.   requested_fmt = DEFAULT_FMT;    /* set default output file format */
  208.  
  209.   /* Scan command line options, adjust parameters */
  210.   
  211.   while ((c = egetopt(argc, argv, "GPRTbdgq:2D")) != EOF)
  212.     switch (c) {
  213.     case 'G':            /* GIF output format. */
  214.       requested_fmt = FMT_GIF;
  215.       break;
  216.     case 'P':            /* PPM output format. */
  217.       requested_fmt = FMT_PPM;
  218.       break;
  219.     case 'R':            /* RLE output format. */
  220.       requested_fmt = FMT_RLE;
  221.       break;
  222.     case 'T':            /* Targa output format. */
  223.       requested_fmt = FMT_TARGA;
  224.       break;
  225.     case 'b':            /* Enable cross-block smoothing. */
  226.       cinfo.do_block_smoothing = TRUE;
  227.       break;
  228.     case 'd':            /* Debugging. */
  229.       e_methods.trace_level++;
  230.       break;
  231.     case 'g':            /* Force grayscale output. */
  232.       cinfo.out_color_space = CS_GRAYSCALE;
  233.       break;
  234.     case 'q':            /* Do color quantization. */
  235.       { int val;
  236.     if (optarg == NULL)
  237.       usage(argv[0]);
  238.     if (sscanf(optarg, "%d", &val) != 1)
  239.       usage(argv[0]);
  240.     cinfo.desired_number_of_colors = val;
  241.       }
  242.       cinfo.quantize_colors = TRUE;
  243.       break;
  244.     case '2':            /* Use two-pass quantization. */
  245.       cinfo.two_pass_quantize = TRUE;
  246.       break;
  247.     case 'D':            /* Suppress dithering in color quantization. */
  248.       cinfo.use_dithering = FALSE;
  249.       break;
  250.     case '?':
  251.     default:
  252.       usage(argv[0]);
  253.       break;
  254.     }
  255.  
  256.   /* If -d appeared, print version identification */
  257.   if (e_methods.trace_level > 0)
  258.     fprintf(stderr, "Independent JPEG Group's DJPEG, version %s\n%s\n",
  259.         JVERSION, JCOPYRIGHT);
  260.  
  261.   /* Select the input and output files */
  262.  
  263. #ifdef TWO_FILE_COMMANDLINE
  264.  
  265. #  ifdef MSDOS
  266.  
  267.   if (optind < argc-2 || optind > argc-1) {
  268.     usage(argv[0]);
  269.   }
  270.   fix_msdos_filename(infname, argv[optind], JPEG_EXT);
  271.   if (optind == argc-2) {
  272.     fix_msdos_filename(outfname, argv[optind+1], DEFAULT_FMT_EXT);
  273.   } else {
  274.     fix_msdos_filename(outfname, argv[optind], DEFAULT_FMT_EXT);
  275.   }
  276.   if ((cinfo.input_file = fopen(infname, READ_BINARY)) == NULL) {
  277.     fprintf(stderr, "%s: can't open %s\n", argv[0], infname);
  278.     exit(2);
  279.   }
  280.   if ((cinfo.output_file = fopen(outfname, WRITE_BINARY)) == NULL) {
  281.     fprintf(stderr, "%s: can't open %s\n", argv[0], outfname);
  282.     exit(2);
  283.   }
  284.  
  285. #  else
  286.  
  287.   if (optind != argc-2) {
  288.     fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
  289.     usage(argv[0]);
  290.   }
  291.   if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  292.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  293.     exit(2);
  294.   }
  295.   if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
  296.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
  297.     exit(2);
  298.   }
  299.  
  300. #  endif
  301.  
  302. #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
  303.  
  304.   cinfo.input_file = stdin;    /* default input file */
  305.   cinfo.output_file = stdout;    /* always the output file */
  306.  
  307.   if (optind < argc-1) {
  308.     fprintf(stderr, "%s: only one input file\n", argv[0]);
  309.     usage(argv[0]);
  310.   }
  311.   if (optind < argc) {
  312.     if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  313.       fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  314.       exit(2);
  315.     }
  316.   }
  317.  
  318. #endif /* TWO_FILE_COMMANDLINE */
  319.   
  320.   /* Set up to read a JFIF or baseline-JPEG file. */
  321.   /* A smarter UI would inspect the first few bytes of the input file */
  322.   /* to determine its type. */
  323. #ifdef JFIF_SUPPORTED
  324.   jselrjfif(&cinfo);
  325. #else
  326.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  327. #endif
  328.  
  329.   /* Do it to it! */
  330.   jpeg_decompress(&cinfo);
  331.  
  332.   /* Release memory. */
  333.   j_d_free_defaults(&cinfo, TRUE);
  334. #ifdef MEM_STATS
  335.   if (e_methods.trace_level > 0) /* Optional memory-usage statistics */
  336.     j_mem_stats();
  337. #endif
  338.  
  339.   /* All done. */
  340.   exit(0);
  341. }
  342.